package ocean.chinacraft.common.world.block.decoration.base;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.FourWayBlock;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;

/**
 * 窗格
 *
 * @author zhang
 * @since 2021/12/9
 */
public abstract class AbstractWindow extends FourWayBlock {

    public AbstractWindow(Properties properties) {
        super(1.0F, 1.0F, 16.0F, 16.0F, 16.0F, properties);
        this.registerDefaultState(this.stateDefinition.any().setValue(NORTH, Boolean.FALSE).setValue(EAST,
                Boolean.FALSE).setValue(SOUTH, Boolean.FALSE).setValue(WEST,
                Boolean.FALSE).setValue(WATERLOGGED, Boolean.FALSE));
    }

    @Override
    public BlockState getStateForPlacement(BlockItemUseContext context) {
        IBlockReader iblockreader = context.getLevel();
        BlockPos blockpos = context.getClickedPos();
        FluidState fluidstate = context.getLevel().getFluidState(context.getClickedPos());
        BlockPos blockpos1 = blockpos.north();
        BlockPos blockpos2 = blockpos.south();
        BlockPos blockpos3 = blockpos.west();
        BlockPos blockpos4 = blockpos.east();
        BlockState blockstate = iblockreader.getBlockState(blockpos1);
        BlockState blockstate1 = iblockreader.getBlockState(blockpos2);
        BlockState blockstate2 = iblockreader.getBlockState(blockpos3);
        BlockState blockstate3 = iblockreader.getBlockState(blockpos4);
        return this.defaultBlockState().setValue(NORTH, this.attachTo(blockstate,
                blockstate.isFaceSturdy(iblockreader, blockpos1, Direction.SOUTH))).setValue(SOUTH,
                this.attachTo(blockstate1, blockstate1.isFaceSturdy(iblockreader, blockpos2,
                        Direction.NORTH))).setValue(WEST, this.attachTo(blockstate2,
                blockstate2.isFaceSturdy(iblockreader, blockpos3, Direction.EAST))).setValue(EAST,
                this.attachTo(blockstate3, blockstate3.isFaceSturdy(iblockreader, blockpos4,
                        Direction.WEST))).setValue(WATERLOGGED, fluidstate.getType() == Fluids.WATER);
    }

    @Override
    public BlockState updateShape(BlockState state1, Direction direction, BlockState state,
                                  IWorld world, BlockPos pos, BlockPos pos1) {
        if (state1.getValue(WATERLOGGED)) {
            world.getLiquidTicks().scheduleTick(pos, Fluids.WATER,
                    Fluids.WATER.getTickDelay(world));
        }

        return direction.getAxis().isHorizontal() ? state1.setValue(PROPERTY_BY_DIRECTION.get(direction),
                this.attachTo(state, state.isFaceSturdy(world, pos1,
                        direction.getOpposite()))) : super.updateShape(state1, direction, state,
                world, pos, pos1);
    }

    @Override
    public VoxelShape getVisualShape(BlockState state, IBlockReader reader, BlockPos pos,
                                     ISelectionContext context) {
        return VoxelShapes.empty();
    }

    @Override
    public boolean skipRendering(BlockState state, BlockState p_200122_2_, Direction direction) {
        if (p_200122_2_.is(this)) {
            if (!direction.getAxis().isHorizontal()) {
                return true;
            }
            if (state.getValue(PROPERTY_BY_DIRECTION.get(direction)) && p_200122_2_.getValue(PROPERTY_BY_DIRECTION.get(direction.getOpposite()))) {
                return true;
            }
        }

        return super.skipRendering(state, p_200122_2_, direction);
    }

    public boolean attachTo(BlockState state, boolean flag) {
        Block block = state.getBlock();
        return !isExceptionForConnection(block) && flag || block instanceof AbstractWindow || block.is(BlockTags.WALLS);
    }

    @Override
    protected void createBlockStateDefinition(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(NORTH, EAST, WEST, SOUTH, WATERLOGGED);
    }
}
